package redisModules

import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/go-redis/redis"
	"github.com/gogf/gf/util/gconv"
	"io/ioutil"
	"net/http"
	"rock/customer/dto"
	"rock/customer/initParam"
	"rock/customer/public"
	"strings"
	"time"
)

var ClientRedis *redis.Client

func InitRedis() {
	proxyList := initParam.RedisConf.ProxyList
	if len(proxyList) == 0 {
		return
	}
	proxy := strings.Split(proxyList[0], ":")
	options := redis.Options{
		Network:            "tcp",
		Addr:               fmt.Sprintf("%s:%s", proxy[0], proxy[1]),
		Dialer:             nil,
		OnConnect:          nil,
		Password:           initParam.RedisConf.Password,
		DB:                 initParam.RedisConf.DB,
		MaxRetries:         0,
		MinRetryBackoff:    0,
		MaxRetryBackoff:    0,
		DialTimeout:        0,
		ReadTimeout:        0,
		WriteTimeout:       0,
		PoolSize:           0,
		MinIdleConns:       0,
		MaxConnAge:         0,
		PoolTimeout:        0,
		IdleTimeout:        0,
		IdleCheckFrequency: 0,
		TLSConfig:          nil,
	}
	// 新建一个client
	ClientRedis = redis.NewClient(&options)

	if initParam.WeChatFAEConf.AppId != "" && initParam.WeChatFAEConf.Secret != "" {
		RedisAppToken(initParam.WeChatFAEConf.AppId, initParam.WeChatFAEConf.Secret, App{})
	}
	if initParam.WeChatClientConf.AppId != "" && initParam.WeChatClientConf.Secret != "" {
		RedisAppToken(initParam.WeChatClientConf.AppId, initParam.WeChatClientConf.Secret, App{})
	}
}

func RedisSendIntroductionText(method string, key string, values int) int {
	if method == "set" {
		ClientRedis.Set(key, values, 0)
		return values
	}
	redisCache := ClientRedis.Get(key)
	val, err := redisCache.Result()
	result := 0
	if err == nil {
		err = json.Unmarshal([]byte(val), &result)
		if err != nil {
			return 0
		}
	} else {
		result = 0
		ClientRedis.Set(key, result, 0)
	}
	return result
}

func RedisSendGroupWelcomeText(method string, key string, values int) int {
	if method == "set" {
		ClientRedis.Set(key, values, 0)
		return values
	}
	redisCache := ClientRedis.Get(key)
	val, err := redisCache.Result()
	result := 0
	if err == nil {
		err = json.Unmarshal([]byte(val), &result)
		if err != nil {
			return 0
		}
	} else {
		result = 0
		ClientRedis.Set(key, result, 0)
	}
	return result
}

func RedisLastAccessSkillGroupId(key string, values int) int {
	if values != 0 {
		ClientRedis.Set(key, values, 0)
		return values
	}
	redisCache := ClientRedis.Get(key)
	val, err := redisCache.Result()
	result := 0
	if err == nil {
		err = json.Unmarshal([]byte(val), &result)
		if err != nil {
			return 0
		}
	} else {
		result = 0
		ClientRedis.Set(key, result, 0)
	}
	return result
}

func RedisChannelTypeUserId(key string, values int) int {
	if values != 0 {
		ClientRedis.Set(key, values, 0)
		return values
	}
	redisCache := ClientRedis.Get(key)
	val, err := redisCache.Result()
	result := 0
	if err == nil {
		err = json.Unmarshal([]byte(val), &result)
		if err != nil {
			return 2
		}
	} else {
		result = 2
		ClientRedis.Set(key, result, 0)
	}
	return result
}

type App struct {
	Token string
}

func RedisAppToken(appId string, secret string, app App) App {
	redisKey := "appIdToken_" + appId
	redisCache := ClientRedis.Get(redisKey)
	val, err := redisCache.Result()
	if err == nil {
		err = json.Unmarshal([]byte(val), &app)
		if err != nil {
			public.ContextNotice(&gin.Context{}, "error", map[string]interface{}{
				"title":     "miniProgramToken",
				"redisKey":  redisKey,
				"val":       val,
				"app":       app,
				"error.err": err,
			})
			return app
		}
	} else {
		urls := fmt.Sprintf(`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s`, appId, secret)
		resp, err := http.Get(urls)
		if err != nil {
			public.ContextNotice(&gin.Context{}, "error", map[string]interface{}{
				"title":          "miniProgramToken",
				"error.http.Get": err,
			})
			return app
		}
		bytes, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			public.ContextNotice(&gin.Context{}, "error", map[string]interface{}{
				"title":                "miniProgramToken",
				"error.ioutil.ReadAll": err,
			})
			return app
		}
		reData := &dto.WeChatMiniProgramOutput{}
		err = json.Unmarshal(bytes, reData)
		if err != nil {
			public.ContextNotice(&gin.Context{}, "error", map[string]interface{}{
				"title":                "miniProgramToken",
				"error.json.Unmarshal": err,
			})
			return app
		}
		if reData.Errcode != 0 {
			public.ContextNotice(&gin.Context{}, "error", map[string]interface{}{
				"title":                 "miniProgramToken",
				"reData.reData.Errcode": reData,
			})
			return app
		}
		app.Token = reData.AccessToken
		ClientRedis.Set(redisKey, app, gconv.Duration(reData.ExpiresIn-1000)*time.Second)
		return app
	}
	return app
}

type ImUser struct {
	MiniProgramAppId string
	UnionId          string
	Openid           string
}

//redisModules.RedisFaeUser("FaeApp_"+reData.Unionid, redisModules.ImUser{
//	MiniProgramAppId: appid,
//	UnionId:          reData.Unionid,
//	Openid:           reData.Openid,
//})
//redisModules.RedisFaeUser("ClientApp_"+reData.Unionid, redisModules.ImUser{
//	MiniProgramAppId: appid,
//	UnionId:          reData.Unionid,
//	Openid:           reData.Openid,
//})
func RedisMiniAppUser(key string, values ImUser) ImUser {
	redisCache := ClientRedis.Get(key)
	val, err := redisCache.Result()
	if err == nil {
		err = json.Unmarshal([]byte(val), &values)
		if err != nil {
			public.ContextNotice(&gin.Context{}, "error", map[string]interface{}{
				"title":           "RedisMiniAppUser",
				"error.Unmarshal": err,
			})
		}
	} else {
		public.ContextNotice(&gin.Context{}, "error", map[string]interface{}{
			"title": "RedisMiniAppUser",
			"error": err,
		})
	}
	return values
}
